By
yusijia
Updated:
RTTI(Run-Time Type Identification,通过运行时类型识别)的含义就是在运行时识别一个对象的类型,其对应的类是Class对象,每个java里面的类都对应一个Class对象(在编写并且编译后),这个对象被保存在这个类的同名class文件里。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
| package lianxi;
import java.util.*; import java.io.*;
interface Birth {}
class man{ man(){ } }
class Human extends man{ Human(){ } }
class Woman extends man implements Birth{ Woman(){ } public void getBirth(){ System.out.println("getBirth!"); } }
public class lianxix { public static void main(String[] args) { Human human = new Human(); Class c1 = human.getClass(); System.out.println(c1.getName()); System.out.println("------------"); Class c2 = null; try{ c2 = Class.forName("lianxi.Woman"); }catch(ClassNotFoundException e){ System.out.println("Not found class of Human"); } System.out.println(c2); System.out.println("------------"); for(Class face : c2.getInterfaces()) System.out.println(face); System.out.println("------------"); Class up = c2.getSuperclass(); Object obj = null; try { obj = up.newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } System.out.println(obj.getClass()); System.out.println("------------"); Class c3 = Woman.class; System.out.println(c3); } }
lianxi.Human ------------ class lianxi.Woman ------------ interface lianxi.Birth ------------ class lianxi.man ------------ class lianxi.Woman
|
当我们调用对象的getClass()方法时,就得到对应Class对象的引用。
除了getClass()方法外,我们还有其他方式调用Class类的对象。
- forName()方法接收一个字符串作为参数,该字符串是类的名字。这将返回相应的Class类对象。
- Woman.class方法是直接调用类的class成员。这将返回相应的Class类对象。
类的字面常量:
为了使用类而做的工作实际包含三个步骤:
加载,这是由类加载器执行的。改步骤将查找字节码,并从字节码中创建一个Class对象。
链接。在链接阶段将验证类中的字节码,为静态域分配存储空间,并且如果必需的话,将解析这个类创建的对其他类的所有引用。
初始化。如果该类具有超类,则对其初始化,执行静态初始化器和静态初始化块。
初始化被延迟到了静态方法(构造器隐式地是静态的)或者非常数静态域进行首次引用时才执行
所以仅适用.class语法来获得对类的引用不会引发初始化,但为了产生class引用,Class.forName()立即就进行了初始化
如果一个static域不是final的,那么在对它访问时,总是要求在它被读取之前,要先进行链接(为这个域分配存储空间)和初始化(初始化存储空间)。
由于static final值是编译器常量,所以这个值不需要对类进行初始化就可以被读取,但如果只是将一个域设置为static或final的,还不足以确保这种行为。
在javaSE5中,Class<?>由于平凡的Class,Class<?>可以与extends关键字结合创建一个范围